/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;
using System.Text;
using System.Xml;

namespace GrooveWebServicesV12Helpers.InfoPathForms
{
    /// <summary>
    /// Represents an InfoPath Form in a InfoPath FormsTool.
    /// </summary>
    public class InfoPathForm : GrooveWebServicesV12Helpers.Forms2.Form
    {
        private GrooveWebServicesV12Helpers.InfoPathForms.InfoPathFormsTool m_InfoPathFormsTool;

        public InfoPathForm(GrooveWebServicesV12Helpers.Forms2.FormsTool i_FormsTool, GrooveWebServicesV12Helpers.GrooveForms2WebService.Form i_Form)
            : base(i_FormsTool, i_Form)
        {
            m_InfoPathFormsTool = (GrooveWebServicesV12Helpers.InfoPathForms.InfoPathFormsTool)i_FormsTool;
        }

        /// <summary>
        /// The InfoPath FormsTool which contains this Form.
        /// </summary>
        public new GrooveWebServicesV12Helpers.InfoPathForms.InfoPathFormsTool FormsTool
        {
            get
            {
                return m_InfoPathFormsTool;
            }
        }

        /// <summary>
        /// Returns the template that defines the specified InfoPath form. The template 
        /// defines the fields and visual design of the form but does not contain any data. 
        /// When you are designing or publishing a form, InfoPath stores the template in an 
        /// .xsn file.
        /// </summary>
        public GrooveWebServicesV12Helpers.InfoPathForms.Template Template
        {
            get
            {
                //  Get initialized reference to web service
                GrooveForms2WebService.GrooveForms2 FormsWebService = GrooveWebServicesV12Helpers.Forms2.FormsTool.CreateInitializedFormsWebService
                    (
                    m_IdentityURL,
                    m_InfoPathFormsTool.URI,
                    Context
                    );

                System.DateTime BeginDateTime = System.DateTime.Now;

                //  Ask service to read template
                GrooveForms2WebService.InfoPathTemplate InfoPathTemplate = FormsWebService.ReadInfoPathTemplate(base.m_Form.URI);

                if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
                {
                    System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
                    System.Diagnostics.Debug.WriteLine("Forms2WebService::ReadInfoPathTemplate, " + TimeSpan.TotalMilliseconds + " ms");
                }

                GrooveWebServicesV12Helpers.InfoPathForms.Template Template = new GrooveWebServicesV12Helpers.InfoPathForms.Template
                    (
                    this,
                    InfoPathTemplate
                    );

                return Template;
            }
        }

        // works for InfoPath forms only
        public string CreateInstance(XmlDocument i_Attachment)
        {
            GrooveWebServicesV12Helpers.Forms2.FormsTool formsTool = this.FormsTool;
            string sFormID = this.ID;
            byte[] byteArray = ConvertToByteArray(i_Attachment.InnerXml);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.NewLineOnAttributes = true;
            settings.Indent = true;
            settings.IndentChars = "   ";
            settings.Encoding = Encoding.Unicode;
            settings.ConformanceLevel = ConformanceLevel.Fragment;

            StringBuilder sb = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(sb, settings);
            writer.WriteStartElement(this.SchemaID);          // 1
            writer.WriteElementString("Forms_Tool_grooveFormID", sFormID);
            writer.WriteStartElement("Forms_Tool_IPContents");   // 2
            writer.WriteStartElement("FileAttachment");         // 3
            writer.WriteElementString("FullName", "InfoPathDocument");
            writer.WriteElementString("Type", "File");
            writer.WriteStartElement("Contents");               // 4
            writer.WriteStartElement("Base64");                 // 5
            writer.WriteBase64(byteArray, 0, byteArray.Length);
            writer.WriteEndElement();                           // 4
            writer.WriteEndElement();                           // 3
            writer.WriteEndElement();                           // 2
            writer.WriteEndElement();                           // 1
            writer.WriteEndElement();                           // 0
            writer.Flush();
            writer.Close();

            // this doesn't do what I want 
            // - I really want just xmlns="http://webservices.groove.net/Groove/2.0/Forms2/"
            // - (This produces nothing)
            NameTable nt = new NameTable();
            nt.Add(@"http://webservices.groove.net/Groove/2.0/Forms2/");

            XmlDocument doc = new XmlDocument(nt);
            doc.LoadXml(sb.ToString());

            GrooveWebServicesV12Helpers.Forms2.RecordDataSet rds
                = new GrooveWebServicesV12Helpers.Forms2.RecordDataSet(formsTool.Schema.Schema,
                                                                       new System.Xml.XmlNode[] { doc.DocumentElement });
            string[] newURIs = formsTool.AddRecords(rds);
            return newURIs[0];
        }

        public static XmlDocument ReadForm(System.Data.DataRow i_DataRow)
        {
            GrooveWebServicesV12Helpers.Forms2.FormFileAttachment[] attachments
                = GrooveWebServicesV12Helpers.Forms2.FormFileAttachment.GetFormFileAttachments(i_DataRow);

            if ((attachments != null) && (attachments.Length == 1))
                return GetFormXml(attachments[0]);
            else
                return null;
        }

        public static XmlDocument GetFormXml(GrooveWebServicesV12Helpers.Forms2.FormFileAttachment i_Attachment)
        {
            System.Text.Encoding enc = System.Text.Encoding.ASCII;
            string attachedString = enc.GetString(i_Attachment.Contents);
            XmlDocument ipDoc = new XmlDocument();
            ipDoc.LoadXml(attachedString);
            return ipDoc;
        }

        // works for InfoPath forms only
        public void UpdateInstance(string i_RecordURI, XmlDocument i_Attachment)
        {
            GrooveWebServicesV12Helpers.Forms2.FormsTool formsTool = this.FormsTool;
            string sFormID = this.ID;
            byte[] byteArray = ConvertToByteArray(i_Attachment.InnerXml);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.NewLineOnAttributes = true;
            settings.Indent = true;
            settings.IndentChars = "   ";
            settings.Encoding = Encoding.Unicode;
            settings.ConformanceLevel = ConformanceLevel.Fragment;

            StringBuilder sb = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(sb, settings);
            writer.WriteStartElement(this.SchemaID);          // 1
            writer.WriteElementString("Forms_Tool_grooveFormID", sFormID);
            writer.WriteElementString("RecordURI", i_RecordURI);
            writer.WriteStartElement("Forms_Tool_IPContents");   // 2
            writer.WriteStartElement("FileAttachment");         // 3
            writer.WriteElementString("FullName", "InfoPathDocument");
            writer.WriteElementString("Type", "File");
            writer.WriteStartElement("Contents");               // 4
            writer.WriteStartElement("Base64");                 // 5
            writer.WriteBase64(byteArray, 0, byteArray.Length);
            writer.WriteEndElement();                           // 4
            writer.WriteEndElement();                           // 3
            writer.WriteEndElement();                           // 2
            writer.WriteEndElement();                           // 1
            writer.WriteEndElement();                           // 0
            writer.Flush();
            writer.Close();

            // this doesn't do what I want 
            // - I really want just xmlns="http://webservices.groove.net/Groove/2.0/Forms2/"
            // - (This produces nothing)
            NameTable nt = new NameTable();
            nt.Add(@"http://webservices.groove.net/Groove/2.0/Forms2/");

            XmlDocument doc = new XmlDocument(nt);
            doc.LoadXml(sb.ToString());

            GrooveWebServicesV12Helpers.Forms2.RecordDataSet rds
                = new GrooveWebServicesV12Helpers.Forms2.RecordDataSet(formsTool.Schema.Schema,
                                                                       new System.Xml.XmlNode[] { doc.DocumentElement });
            formsTool.UpdateRecords(rds);
        }

        private static byte[] ConvertToByteArray(string i_string)
        {
            ASCIIEncoding asc = new ASCIIEncoding();
            byte[] plainByteArray = asc.GetBytes(i_string);
            return plainByteArray;
        }

        private static byte[] ConvertToByteArrayBase64(string i_string)
        {
            ASCIIEncoding asc = new ASCIIEncoding();
            byte[] plainByteArray = asc.GetBytes(i_string);
            string base64String = Convert.ToBase64String(plainByteArray);
            byte[] encodedByteArray = asc.GetBytes(base64String);
            return encodedByteArray;
        }

    }
}
